/*
 *      character.cpp
 *      
 *      2009 Víctor Manuel Ochoa <kanito8a@gmail.com>
 *      
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *      
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *      
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */


#include "animedentity.h"

/*
 * 
 * name: desconocido
 * @param
 * @return
 */
AnimedEntity::AnimedEntity()
{
	m_pLog=&Log::getInstance();
}

/*
 * 
 * name: desconocido
 * @param
 * @return
 */
AnimedEntity::~AnimedEntity()
{
	
}

/*
 * 
 * name: desconocido
 * @param
 * @return
 */
bool AnimedEntity::init(Texture * _texture,Animation _animations[MAX_ANIMATION_NUM],unsigned short _colums_num,unsigned short _rows_num)
{
	if(!Anim::init(_texture,_colums_num,_rows_num))
	{
		Anim::freeMemory();
		m_pLog->error("Unable to create AnimedEntity"); 
		return false;	
	}
	
	for(int i=0;i<MAX_ANIMATION_NUM;i++)
	{		
		//~ for(unsigned short n=0;n<_animations[i].frames.size();n++)m_animations[i].frames.push_back(_animations[i].frames[n]);
		m_animations[i].frames=_animations[i].frames;
		//~ copy(_animations[i].frames.begin(), _animations[i].frames.end(),m_animations[i].frames.begin());
		m_animations[i].frame_time=_animations[i].frame_time;
	}
	setAnimation(WALK);
	
	for(int j=0;j<MAX_FRAME_P0INTS;j++)m_attached_entities[j]=NULL;
	
	m_pLog->debug("+ AnimedEntity initialized"); 
	return true;
}

/*
 * 
 * name: desconocido
 * @param
 * @return
 */
bool AnimedEntity::init(float _position[3],float _rotation,float _scale[3],Texture *_texture,unsigned short _colums_num,unsigned short _rows_num)
{
	if(!Anim::init(_position,_rotation,_scale,_texture,_colums_num,_rows_num))
	{
		Anim::freeMemory();
		m_pLog->error("Unable to create AnimedEntity"); 
		return false;	
	}	
	setAnimation(STAND);
	for(int i=0;i<MAX_FRAME_P0INTS;i++)m_attached_entities[i]=0;
	
	m_pLog->debug("+ AnimedEntity initialized"); 
	return true;
}

/*
 * 
 * name: desconocido
 * @param
 * @return
 */
bool AnimedEntity::init(TextureManager *_texture_manager,const char *_cfg_filename)
{
	FileReader description_file;
	Texture *new_texture;
	AnimationFramePoints frame_points[MAX_FRAME_P0INTS];	
	int columns;
	int rows;
	int anim_num;
	int frame_num;	
	char *value;
	char *value2;
	char anim_name[16];
	char animtime_name[16];
	char animframepoint_name[25];
	
	if(!description_file.init(_cfg_filename))
	{
		description_file.freeMemory();
		m_pLog->error("Unable to create AnimedEntity"); 
		return false;
	}
	
	new_texture=_texture_manager->newTexture(description_file.getValue(STRING_FILENAME,1));
	columns=atoi(description_file.getValue(STRING_COLUMNS,1));
	rows=atoi(description_file.getValue(STRING_ROWS,1));
	
	if(!new_texture || columns==0 || rows==0)
	{
		description_file.freeMemory();
		freeMemory();
		m_pLog->error("Unable to create AnimedEntity"); 
		return false;			
	}
	
	// Animations Load
	anim_num=1;
	frame_num=1;
	sprintf(anim_name,"%s%d",STRING_ANIM,anim_num);
	sprintf(animtime_name,"%s%d",STRING_ANIMTIME,anim_num);
	
	while(anim_num<=MAX_ANIMATION_NUM)
	{
		value=description_file.getValue(anim_name,frame_num);
		while(value)
		{
			m_animations[anim_num-1].frames.push_back(atoi(value));
			++frame_num;
			value=description_file.getValue(anim_name,frame_num);
		}
		
		// Animation Frame time load
		value=description_file.getValue(animtime_name,1);
		if(value!=0)
		{
			m_animations[anim_num-1].frame_time=atoi(value);
		}
		else
		{
			m_animations[anim_num-1].frame_time=FRAME_TIME_DEFAULT;
		}
		
		frame_num=1;
		++anim_num;
		sprintf(anim_name,"%s%d",STRING_ANIM,anim_num);
		sprintf(animtime_name,"%s%d",STRING_ANIMTIME,anim_num);

	}
	
	// Framepoints load
	frame_num=1;
	anim_num=1;
	sprintf(animframepoint_name,"%s%d",STRING_ANIMFRAMEPOINT,anim_num);
	
	while(anim_num<=MAX_FRAME_P0INTS)
	{
		value=description_file.getValue(animframepoint_name,frame_num);
		value2=description_file.getValue(animframepoint_name,frame_num+1);
		FramePoint p;
		
		while(value && value2)
		{			
			p.x=atoi(value);
			p.y=atoi(value2);
			frame_points[anim_num-1].framePoints.push_back(p);	
			frame_num+=2;

			value=description_file.getValue(animframepoint_name,frame_num);
			value2=description_file.getValue(animframepoint_name,frame_num+1);
		}
		
		frame_num=1;
		++anim_num;
		sprintf(animframepoint_name,"%s%d",STRING_ANIMFRAMEPOINT,anim_num);
	}
	
	setAnimationFramePoints(frame_points);

	for(int i=0;i<MAX_FRAME_P0INTS;i++)
	{
		m_attached_entities[i]=0;
	}
		
	Anim::init(new_texture,columns,rows);
	setAnimation(STAND);
	
	description_file.freeMemory();	

	m_pLog->debug("+ Animed entity");
	return true;
}

/*
 * 
 * name: desconocido
 * @param
 * @return
 */
void AnimedEntity::freeMemory()
{
	for(int i=0;i<MAX_FRAME_P0INTS;i++)
	{
		if(m_attached_entities[i]!=0)
		{
			m_attached_entities[i]->setAlive(false);
			m_attached_entities[i]=0;
		}
	}
	Anim::freeMemory();
	m_pLog->debug("- AnimedEntity free"); 
	m_pLog=0;	
}

/*
 * 
 * name: desconocido
 * @param
 * @return
 */
void AnimedEntity::update()
{
	Anim::update();	
	
	if(Anim::endOfAnim())
	{
		Anim::restart();
	}
	
	for(int i=0;i<MAX_FRAME_P0INTS;i++)
	{
		if(m_attached_entities[i]!=0)
		{
			const Vector2 *pos=getPosition();
			Vector2 new_pos;
			FramePoint modif=getFramePoint(i);
			if(isFlipped())
				new_pos.x=pos->x-modif.x;
			else
				new_pos.x=pos->x+modif.x;
				
			new_pos.y=pos->y+modif.y;
			m_attached_entities[i]->setPosition(new_pos);
		}
	}
}

/*
 * 
 * name: desconocido
 * @param
 * @return
 */
void AnimedEntity::flip()
{
	Entity::flip();
	for(int i=0;i<MAX_FRAME_P0INTS;i++){
		if(m_attached_entities[i]!=0)
			m_attached_entities[i]->flip();
	}
}
